<?php
class C_TicketFinder extends Controller {
	const RESULT_TYPE_FINAL    =   'final';
	const RESULT_TYPE_SELECTION    =   'selection';
	function __construct($template_mod = "general"){
		parent::Controller();
		$this->template_mod = $template_mod;
        $this->view->path = 'ticket_finder';
	}

	public function actionSearchOutPatientByCode($patientCode = 0) {
		if (isset($_POST['patientCode'])) {
			$patientCode =   $_POST['patientCode'];
		}
		$result = array(
		  'error'   =>  array('code'=>CoreErrorCode::NORMAL, 'mess' => ''),
          'result'  =>  ''
		);
		// Check patient existed or not
		$objPatient   =   Celini::newORDO('Patient');
		$patientId    =   $objPatient->checkPatientByCode($patientCode);

		if (!$patientId) {
		    $result['error']['code'] =   "NOTFOUND";
		    $result['error']['mess'] =   L10nHelper::_('Not found patient code: <b>%s</b>', $patientCode);
		    return json_encode($result);
		}
		$ticketList   =   Celini::newORDO('Ticket')->getTicketListByPatient($patientId, EnumerationConstant::PATIENT_TYPE_OUTPATIENT_KEY,
        	false, EnumerationConstant::EXAMINATION_TYPE_SERVICE_KEY);
		// Check if the patient have opening tickets
		if (count($ticketList) == 0) {
		    $result['error']['code'] =   "NOTFOUND";
		    $result['error']['mess'] =   L10nHelper::_('The patient with patient code <b>%s</b> has no opening tickets', $patientCode);
		    return json_encode($result);
		}

		try {
			$hisLoader = new HISFileLoader();
			$trlOutPayment = $hisLoader->getObj('C_OutPayment');
            $res   =   json_decode($trlOutPayment->actionViewTicketPaymentAjax($ticketList[0]['ticket_id']), true);
            $result['result']   =   $res['result'];
            
			$ctrlPaymentCommon = $hisLoader->getObj('C_PaymentCommon');
            $result['result']['ticketList']    =   $ctrlPaymentCommon->renderTicketListOption($ticketList, $ticketList[0]['ticket_id']);
			
		}catch (HISFileLoaderException $e) {
			$result['error']['code'] = CoreErrorCode::COMMON_ERROR;
            $result['error']['mess'] = CoreErrorCode::getErrorMess(CoreErrorCode::COMMON_ERROR);
		}
		return json_encode($result);
	}
    
	/**
	 * Search outpatient by patient name.
	 *
	 * @param string $patientName Patient name
	 * @return json Retsult object
	 */
	public function actionSearchOutPatientByName($patientName = '') {
	   if (isset($_POST['patientName'])) {
            $patientName =   Utils::sanitizeText($_POST['patientName']);
	   }
	   $result = array(
          'error'   =>  array('code'=>CoreErrorCode::NORMAL, 'mess' => ''),
          'result'  =>  ''
        );
        // Check patient existed or not
        $patientList    =   Celini::newORDO('Patient')->searchPatientByName($patientName);
        if (count($patientList) == 0) {
            $result['error']['code'] =   "NOTFOUND";
            $result['error']['mess'] =   L10nHelper::_('Not found patient name: <b>%s</b>', $patientName);
            return json_encode($result);
        }
        try {
            // Only one patient found: Return error if the patient has no tickets, or else return payment result.
            if (count($patientList) == 1) {
                $ticketList   =   Celini::newORDO('Ticket')->getTicketListByPatient($patientList[0]['person_id'], EnumerationConstant::PATIENT_TYPE_OUTPATIENT_KEY,
                false, EnumerationConstant::EXAMINATION_TYPE_SERVICE_KEY);
                // Check if the patient has tickets
                if (count($ticketList) == 0) {
                    $result['error']['code'] =   "NOTFOUND";
                    $result['error']['mess'] =   L10nHelper::_('The patient <b>%s</b> has no tickets', $patientName);
                    return json_encode($result);
                }
                else {
                    $hisLoader = new HISFileLoader();
                    $trlOutPayment = $hisLoader->getObj('C_OutPayment');
                    $res   =   json_decode($trlOutPayment->actionViewTicketPaymentAjax($ticketList[0]['ticket_id']), true);
                    $result['result']   =   $res['result'];
                    $result['result']['type']   =   self::RESULT_TYPE_FINAL;
                }
            }
            // More than 1 patients found: Build html for patient selection.
            else {
                // Get patient ids
                $patientIds =   array();
                foreach ($patientList as $item) {
                    $patientIds[]   =   $item['person_id'];
                }
                $list   =   Celini::newORDO('Ticket')->getTicketListByPatient($patientIds, EnumerationConstant::PATIENT_TYPE_OUTPATIENT_KEY,
                    false, EnumerationConstant::EXAMINATION_TYPE_SERVICE_KEY);
                $ticketList =   array();
                foreach ($list as $ticket) {
                    if (!isset($ticketList[$ticket['patient_id']])) {
                        $ticketList[$ticket['patient_id']]  =   $ticket;
                    }
                    else {
                        continue;
                    }
                }
                $ticketNum  =   count($ticketList);
                if ($ticketNum == 0) {
                    $result['error']['code'] =   "NOTFOUND";
                    $result['error']['mess'] =   L10nHelper::_('The patient <b>%s</b> has no tickets', $patientName);
                    return json_encode($result);
                }
                 
                if ($ticketNum == 1) {
                    $hisLoader = new HISFileLoader();
                    $trlOutPayment = $hisLoader->getObj('C_OutPayment');
                    $ticket =   array_shift($ticketList);
                    $res   =   json_decode($trlOutPayment->actionViewTicketPaymentAjax($ticket['ticket_id']), true);
                    $result['result']   =   $res['result'];
                    $result['result']['type']   =   self::RESULT_TYPE_FINAL;
                }
                else {
                    $hisLoader = new HISFileLoader();
                    $trlOutPayment = $hisLoader->getObj('C_PaymentCommon');
                    $result['result']['type']   =   self::RESULT_TYPE_SELECTION;
                    $result['result']['html']   =   $trlOutPayment->renderTicketList($ticketList, $_POST['jsFunction'], $_POST['dialogId']);
                }
             }
        }
        catch (HISFileLoaderException $e) {
            $result['error']['code'] = CoreErrorCode::COMMON_ERROR;
            $result['error']['mess'] = CoreErrorCode::getErrorMess(CoreErrorCode::COMMON_ERROR);
        }
        return json_encode($result);
	}

	/**
	 * Seach insurance patient by given patient code.
	 *
	 * @param string $patientCode
	 * @return json object
	 *     If patient with provided code does not exist, return error "Patient with provided code does not exist".
	 *     If there is a patient with provided code but the patient does not have any ticket of insurance type,
	 *         return error "The patient has not any insurance ticket"
	 */
    public function actionSearchInsurancePatientByCode($patientCode = 0) {
        if (isset($_POST['patientCode'])) {
            $patientCode =   $_POST['patientCode'];
        }
        $result = array(
          'error'   =>  array('code'=>CoreErrorCode::NORMAL, 'mess' => ''),
          'result'  =>  ''
        );
        // Check patient existed or not
        $objPatient   =   Celini::newORDO('Patient');
        $patientId    =   $objPatient->checkPatientByCode($patientCode);
        if (!$patientId) {
            $result['error']['code'] =   "NOTFOUND";
            $result['error']['mess'] =   L10nHelper::_('Not found patient code: <b>%s</b>', $patientCode);
            return json_encode($result);
        }
        // Check if the patient has insurance ticket
        $ticketList   =   Celini::newORDO('Ticket')->getTicketListByPatient($patientId, EnumerationConstant::PATIENT_TYPE_OUTPATIENT_KEY,
        	false, EnumerationConstant::EXAMINATION_TYPE_INSURANCE_KEY);
        if (count($ticketList) == 0) {
            $result['error']['code'] =   "NOTFOUND";
            $result['error']['mess'] =   L10nHelper::_('The patient with patient code <b>%s</b> has no insurance tickets', $patientCode);
            return json_encode($result);
        }
        // Patient's demographic info
        $objPerson    =   Celini::newORDO('Person',$patientId);
        $result['result']['patientCode']    =   $patientCode;
        $result['result']['patientName']    =   $objPerson->getName();
        $objDate    =   DateObject::createFromISO($objPerson->get('date_of_birth'));
        $result['result']['birthDay']       =   $objDate->getYear();
        try {
            $hisLoader = new HISFileLoader();
            $ctrlPaymentCommon = $hisLoader->getObj('C_PaymentCommon');
            $result['result']['ticketList']    =   $ctrlPaymentCommon->renderTicketListOption($ticketList, $ticketList[0]['ticket_id']);
            
            $trlOutPayment = $hisLoader->getObj('C_InsurancePayment');
            $res   =   json_decode($trlOutPayment->actionViewTicketPaymentAjax($ticketList[0]['ticket_id']), true);
            $result['result']   =   $res['result'];

        }catch (HISFileLoaderException $e) {
            $result['error']['code'] = CoreErrorCode::COMMON_ERROR;
            $result['error']['mess'] = CoreErrorCode::getErrorMess(CoreErrorCode::COMMON_ERROR);
        }
        return json_encode($result);
    }
    
    /**
     * Search insurance patient by patient name.
     *
     * @param string $patientName Patient name
     * @return json Result object
     */
    public function actionSearchInsurancePatientByName($patientName = '') {
       if (isset($_POST['patientName'])) {
            $patientName =   Utils::sanitizeText($_POST['patientName']);
       }
       $result = array(
          'error'   =>  array('code'=>CoreErrorCode::NORMAL, 'mess' => ''),
          'result'  =>  ''
        );
        // Check patient existed or not
        $patientList    =   Celini::newORDO('Patient')->searchPatientByName($patientName);
        if (count($patientList) == 0) {
            $result['error']['code'] =   "NOTFOUND";
            $result['error']['mess'] =   L10nHelper::_('Not found patient name: <b>%s</b>', $patientName);
            return json_encode($result);
        }
        try {
            // Only one patient found: Return error if the patient has no tickets, or else return payment result.
            if (count($patientList) == 1) {
                $ticketList   =   Celini::newORDO('Ticket')->getTicketListByPatient($patientList[0]['person_id'], EnumerationConstant::PATIENT_TYPE_OUTPATIENT_KEY,
                    false, EnumerationConstant::EXAMINATION_TYPE_INSURANCE_KEY);
                // Check if the patient has tickets
                if (count($ticketList) == 0) {
                    $result['error']['code'] =   "NOTFOUND";
                    $result['error']['mess'] =   L10nHelper::_('The patient <b>%s</b> has no insurance tickets', $patientName);
                    return json_encode($result);
                }
                else {
                    $hisLoader = new HISFileLoader();
                    $trlOutPayment = $hisLoader->getObj('C_InsurancePayment');
                    $res   =   json_decode($trlOutPayment->actionViewTicketPaymentAjax($ticketList[0]['ticket_id']), true);
                    $result['result']   =   $res['result'];
                    $result['result']['type']   =   self::RESULT_TYPE_FINAL;
                }
            }
            // More than 1 patients found: Build html for patient selection.
            else {
                // Get patient ids
                $patientIds =   array();
                foreach ($patientList as $item) {
                    $patientIds[]   =   $item['person_id'];
                }
                $list   =   Celini::newORDO('Ticket')->getTicketListByPatient($patientIds, EnumerationConstant::PATIENT_TYPE_OUTPATIENT_KEY,
                    false, EnumerationConstant::EXAMINATION_TYPE_INSURANCE_KEY);
                $ticketList =   array();
                foreach ($list as $ticket) {
                    if (!isset($ticketList[$ticket['patient_id']])) {
                        $ticketList[$ticket['patient_id']]  =   $ticket;
                    }
                    else {
                        continue;
                    }
                }
                $ticketNum  =   count($ticketList);
                if ($ticketNum == 0) {
                    $result['error']['code'] =   "NOTFOUND";
                    $result['error']['mess'] =   L10nHelper::_('The patient <b>%s</b> has no insurance tickets', $patientName);
                    return json_encode($result);
                }
                 
                if ($ticketNum == 1) {
                    $hisLoader = new HISFileLoader();
                    $trlOutPayment = $hisLoader->getObj('C_InsurancePayment');
                    $ticket =   array_shift($ticketList);
                    $res   =   json_decode($trlOutPayment->actionViewTicketPaymentAjax($ticket['ticket_id']), true);
                    $result['result']   =   $res['result'];
                    $result['result']['type']   =   self::RESULT_TYPE_FINAL;
                }
                else {
                    $hisLoader = new HISFileLoader();
                    $trlOutPayment = $hisLoader->getObj('C_PaymentCommon');
                    $result['result']['type']   =   self::RESULT_TYPE_SELECTION;
                    $result['result']['html']   =   $trlOutPayment->renderTicketList($ticketList, $_POST['jsFunction'], $_POST['dialogId']);
                }
             }
        }
        catch (HISFileLoaderException $e) {
            $result['error']['code'] = CoreErrorCode::COMMON_ERROR;
            $result['error']['mess'] = CoreErrorCode::getErrorMess(CoreErrorCode::COMMON_ERROR);
        }
        return json_encode($result);
    }
}
?>